package dm.ast.model.gen;

import dm.ast.DmASTNode;
import dm.ast.DmBoolOperator;
import dm.ast.DmDataType;
import dm.ast.DmOperator;
import test.utility.Randomly;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class OperatorGen{
    public static String[] MATH1_OPERATORS_PREFIX = {"+", "-"};
    public static String[] MATH2_OPERATORS = {"+", "-", "*", "/"};
    public static String[] STRING2_OPERATORS = {"||"};
    public static String[] TIME_OPERATORS = {"+", "-"};  //时间运算
    public static String[] INTERVAL_OPERATORS = {"+", "-"};  //时间间隔运算

    public static String[] BOOL1_OPERATORS_PREFIX = {"NOT"};
    public static String[] BOOL2_OPERATORS = {"AND", "OR"};
    public static String[] LOGIC_OPERATORS = {">", "<", "=", "!=", ">=", "<=", "<>"};
    public static String[] NULL_OPERATORS_POSTFIX = {"IS NULL", "IS NOT NULL"};

    public static List<DmOperator> mathOps = new ArrayList<DmOperator>();
    public static List<DmOperator> stringOps = new ArrayList<DmOperator>();
    public static List<DmOperator> timeOps = new ArrayList<DmOperator>();
    public static List<DmOperator> intervalOps = new ArrayList<DmOperator>();

    public static List<DmBoolOperator> boolOps = new ArrayList<DmBoolOperator>();
    public static List<DmOperator> inOps = new ArrayList<DmOperator>();
    public static List<DmOperator> logicOps = new ArrayList<DmOperator>();
    public static List<DmOperator> nullOps = new ArrayList<DmOperator>();

    //initLow:用于初始化DmOperator集合
    //@ops:初始化的DmOperator集合
    //@opstring: 操作符字符串标志
    //@expNum :操作数个数
    //@isPre: 前缀操作符标志
    private static void initLow(List<DmOperator> ops, String[] opstring, int expNum, boolean isPre) {
        for (int i = 0; i < opstring.length; i++) {
            DmOperator operator = new DmOperator();
            if (expNum == 1) {
                operator.setOperator(opstring[i], isPre);
            } else {
                operator.setOperator(opstring[i]);

            }
            ops.add(operator);
        }
    }

    private static void initBoolLow(List<DmBoolOperator> ops, String[] opstring, int expNum, boolean isPre) {
        for (int i = 0; i < opstring.length; i++) {
            DmBoolOperator operator = new DmBoolOperator();
            if (expNum == 1) {
                operator.setOperator(opstring[i], isPre);
            } else {
                operator.setOperator(opstring[i]);

            }
            ops.add(operator);
        }
    }

    //对外提供的生成接口
    public static DmOperator expOperatorRandom(DmDataType rType) {
        if (rType == null) {
            throw new AssertionError();
        }
        switch (rType) {
            case INT:
                return mathOperatorRandom();
            case CHAR:
                return stringOperatorRandom();
            case TIME:
                return timeDmOperatorRandom();
            case INTERVAL:
                return intervlOperatorRandom(); //命名有些问题
            default:
                throw new AssertionError();
        }
    }

    //生成数学运算操作符
    public synchronized static DmOperator mathOperatorRandom() {
        if (mathOps.size() == 0) {
            initLow(mathOps, MATH1_OPERATORS_PREFIX, 1, true);
            initLow(mathOps, MATH2_OPERATORS, 2, true);
        }
        return Randomly.fromList(mathOps);
    }

    //生成字符串运算操作符
    public synchronized static DmOperator stringOperatorRandom() {
        if (stringOps.size() == 0) {
            initLow(stringOps, STRING2_OPERATORS, 2, true);
        }
        return Randomly.fromList(stringOps);
    }

    //生成时间运算操作符
    public synchronized static DmOperator timeDmOperatorRandom() {
        if (timeOps.size() == 0) {
            initLow(timeOps, TIME_OPERATORS, 2, false);
        }
        return Randomly.fromList(timeOps);
    }

    //生成时间间隔运算操作符
    public synchronized static DmOperator intervlOperatorRandom() {
        if (intervalOps.size() == 0) {
            initLow(intervalOps, INTERVAL_OPERATORS, 2, false);
        }
        return Randomly.fromList(intervalOps);
    }

    //生成bool运算操作符
    public synchronized static DmBoolOperator boolOperatorRandom() {
        if (boolOps.size() == 0) {
            initBoolLow(boolOps, BOOL1_OPERATORS_PREFIX, 1, true);
            initBoolLow(boolOps, BOOL2_OPERATORS, 2, false);
        }
        return Randomly.fromList(boolOps);
    }

    //生成logic运算操作符
    public synchronized static DmOperator logicOperatorRandom() {
        if (logicOps.size() == 0) {
            initLow(logicOps, LOGIC_OPERATORS, 2, false);
        }
        return Randomly.fromList(logicOps);
    }

    //生成null运算操作符
    public synchronized static DmOperator nullOperatorRandom() {
        if (nullOps.size() == 0) {
            initLow(nullOps, NULL_OPERATORS_POSTFIX, 1, false);
        }
        return Randomly.fromList(nullOps);
    }

}
